home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / GenInstrTopology.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  6.5 KB  |  180 lines  |  [TEXT/KAHL]

  1. /* GenInstrTopology.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "GenInstrTopology.h"
  31. #include "Array.h"
  32. #include "OscillatorSpecifier.h"
  33. #include "ModulationSpecifier.h"
  34. #include "Memory.h"
  35.  
  36.  
  37. /* here's the routine that recursively traverses the graph.  SourceOscillator */
  38. /* is no longer on the Independency list and is on the Scratch list */
  39. static MyBoolean            TraverseOscillator(OscillatorRec* SourceOscillator,
  40.                                                 ArrayRec* ScratchList, ArrayRec* IndependencyList)
  41.     {
  42.         ModulationSpecRec*    ListOfModulators;
  43.         long                                NumModulators;
  44.         long                                Scan;
  45.  
  46.         CheckPtrExistence(SourceOscillator);
  47.         CheckPtrExistence(ScratchList);
  48.         CheckPtrExistence(IndependencyList);
  49.         ERROR(ArrayFindElement(ScratchList,SourceOscillator) != -1,PRERR(ForceAbort,
  50.             "TraverseOscillator:  source oscillator is still on the scratch list"));
  51.         ERROR(ArrayFindElement(IndependencyList,SourceOscillator) == -1,PRERR(ForceAbort,
  52.             "TraverseOscillator:  source oscillator is not on the independency list"));
  53.  
  54.         ListOfModulators = OscillatorGetModulatorInputList(SourceOscillator);
  55.         NumModulators = GetModulationSpecNumEntries(ListOfModulators);
  56.         for (Scan = 0; Scan < NumModulators; Scan += 1)
  57.             {
  58.                 OscillatorRec*            PossibleOscillator;
  59.                 long                                Position;
  60.  
  61.                 PossibleOscillator = GetModulationOscillatorRef(ListOfModulators,Scan);
  62.                 CheckPtrExistence(PossibleOscillator);
  63.                 Position = ArrayFindElement(ScratchList,PossibleOscillator);
  64.                 if (Position >= 0)
  65.                     {
  66.                         /* it's there -- remove it & put it on the scratch list */
  67.                         ArrayDeleteElement(ScratchList,Position);
  68.                         if (!ArrayAppendElement(IndependencyList,PossibleOscillator))
  69.                             {
  70.                                 return False;
  71.                             }
  72.                     }
  73.                  else
  74.                     {
  75.                         /* it wasn't there.  it must be on the list already.  just make sure. */
  76.                         ERROR(ArrayFindElement(IndependencyList,PossibleOscillator) == -1,
  77.                             PRERR(ForceAbort,"TraverseOscillator:  oscillator not on either list"));
  78.                     }
  79.             }
  80.  
  81.         return True;
  82.     }
  83.  
  84.  
  85. /* this routine takes an array of oscillators and builds a series of independent */
  86. /* oscillator groups based on which oscillators depend on others for modulation */
  87. /* input.  the result is an array containing arrays of OscillatorRec's. */
  88. /* for the moment, the ordering is undefined.  if this turns out to matter, or I */
  89. /* implement optimized non-cyclic modulation, then this will need to be changed */
  90. /* by putting them in the proper order and generating dependency annotations. */
  91. struct ArrayRec*            BuildOscillatorLists(struct OscillatorRec** OscillatorArray,
  92.                                                 long NumOscillators)
  93.     {
  94.         ArrayRec*                        MasterList;
  95.         ArrayRec*                        ScratchList;
  96.         long                                Scan;
  97.  
  98.         CheckPtrExistence(OscillatorArray);
  99.         /* this is just a typical graph traversal algorithm. */
  100.         /*   - take a node (oscillator) out of the list */
  101.         /*   - add it to the independency list */
  102.         /*   - for each oscillator it depends on which isn't in our list yet */
  103.         /*      - add it to our list */
  104.         /*      - remove it from the global list */
  105.         /*      - recursively add the things it depends on. */
  106.         /* this makes one list of independencies.  add it to our master list and */
  107.         /* continue until there are no oscillators left */
  108.  
  109.         MasterList = NewArray();
  110.         if (MasterList == NIL)
  111.             {
  112.              FailurePoint1:
  113.                 return NIL;
  114.             }
  115.  
  116.         ScratchList = NewArray(); /* this list will contain all of the oscillators */
  117.         if (ScratchList == NIL)
  118.             {
  119.              FailurePoint2:
  120.                 while (ArrayGetLength(MasterList) != 0)
  121.                     {
  122.                         /* master list is an array of arrays. */
  123.                         DisposeArray((ArrayRec*)ArrayGetElement(MasterList,0));
  124.                         ArrayDeleteElement(MasterList,0);
  125.                     }
  126.                 DisposeArray(MasterList);
  127.                 goto FailurePoint1;
  128.             }
  129.  
  130.         for (Scan = 0; Scan < NumOscillators; Scan += 1)
  131.             {
  132.                 PRNGCHK(OscillatorArray,&(OscillatorArray[Scan]),sizeof(OscillatorArray[Scan]));
  133.                 if (!ArrayAppendElement(ScratchList,OscillatorArray[Scan]))
  134.                     {
  135.                      FailurePoint3:
  136.                         DisposeArray(ScratchList);
  137.                         goto FailurePoint2;
  138.                     }
  139.             }
  140.  
  141.         /* now, do it until we have no more things */
  142.         while (ArrayGetLength(ScratchList) > 0)
  143.             {
  144.                 ArrayRec*                        IndependencyList;
  145.                 OscillatorRec*            Root;
  146.  
  147.                 IndependencyList = NewArray();
  148.                 if (IndependencyList == NIL)
  149.                     {
  150.                      FailurePoint4:
  151.                         goto FailurePoint3;
  152.                     }
  153.  
  154.                 Root = (OscillatorRec*)ArrayGetElement(ScratchList,0);
  155.                 ArrayDeleteElement(ScratchList,0);
  156.                 if (!ArrayAppendElement(IndependencyList,Root))
  157.                     {
  158.                      FailurePoint4a:
  159.                         DisposeArray(IndependencyList);
  160.                         goto FailurePoint4;
  161.                     }
  162.  
  163.                 if (!TraverseOscillator(Root,ScratchList,IndependencyList))
  164.                     {
  165.                      FailurePoint4b:
  166.                         goto FailurePoint4a;
  167.                     }
  168.  
  169.                 if (!ArrayAppendElement(MasterList,IndependencyList))
  170.                     {
  171.                      FailurePoint4c:
  172.                         goto FailurePoint4b;
  173.                     }
  174.             }
  175.  
  176.         DisposeArray(ScratchList);
  177.  
  178.         return MasterList;
  179.     }
  180.